# 合并所有csv文件，对阿贝尔群进行额外处理，导出子群分解结果
import re
import os
import csv


def extract_values_from_string(input_string):
    pattern = r"(\d+),(\d+),\[\s*(\d+(?:,\s*\d+)*)\s*\]"
    match = re.match(pattern, input_string)
    if match:
        first_int = int(match.group(1))
        second_int = int(match.group(2))
        int_array = [int(num) for num in match.group(3).split(",")]
        return first_int, second_int, int_array
    else:
        return None


def process_abelian_groups(file_path):
    result = dict()
    with open(file_path, 'r') as file:
        next(file)  # skip first invalid line
        for line in file:
            order, index, invariants = extract_values_from_string(line)
            result[f"{order}-{index}"] = invariants
    return result


def order_list(lst):
    def key_func(item):
        parts = item.split("-")
        return int(parts[0]), int(parts[1])

    return sorted(lst, key=key_func)


abelian_groups = process_abelian_groups(
    "abelian-groups/abelian-groups-with-invariants.data")
csv_files = [os.path.splitext(file)[0] for file in os.listdir(
    '.') if file.endswith('.csv') and file != 'all_groups.csv']
csv_files = order_list(csv_files)
with open('all_groups.csv', 'w', newline='') as file:
    csv_writer = csv.writer(file)
    csv_writer.writerow(['order', 'index', 'isabelian',
                        'invariants', 'v', 'k1', 'k2', 'e', 'lambda', 'n', 'dsp'])
    for csv_file in csv_files:
        with open(f"{csv_file}.csv", "r") as cur_csv:
            cur_csv_reader = csv.reader(cur_csv)
            _ = next(cur_csv_reader)  # skip header row
            # header = next(cur_csv_reader)
            # num_columns = len(heade)
            for line in cur_csv_reader:
                order, index, v, k1, k2, e, lambd, n, dsp = line
                if csv_file in abelian_groups:
                    csv_writer.writerow(
                        [order, index, True, abelian_groups[csv_file], order, k1, k2, e, lambd, n, dsp])
                else:
                    csv_writer.writerow(
                        [order, index, False, [], order, k1, k2, e, lambd, n, dsp])
